/*  File Name	: GlobalDB.cpp
 *  Author		: Pang Jiacai
 *	 E-mail		: 823960168@qq.com
 *  Created on	: 2012-12-13
 *  Description:
 */
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <stdio.h>
#include "MySqlDB.h"
#include "Logger.h"
#include "Cmd.h"
#include "DBRowName.h"
#include "Configurator.h"
#include "ComDefine.h"
#include "EnginePlayer.h"
#include "ChatMonitor.h"
#include "DBMonitor.h"

#include "cppconn/prepared_statement.h"
#include "cppconn/metadata.h"
#include "cppconn/resultset_metadata.h"
#include "cppconn/exception.h"
#include "cppconn/warning.h"

/*
 * if success,return role id,else return error code
 */
int MySqlDB::create_global_role(int roleid,std::string account,std::string pwd,int sex)
{
	try
	{
		MyConnection conn = this->get_conn();
		if (NULL == conn.conn_)
		{
			return -1;
		}
		sql::Statement *state = conn.conn_->createStatement();
		if (NULL == state)
		{
			return -1;
		}

		char sql[512] = { 0 };
		std::string sql_str =
				CONFIG_INSTANCE->sql_cfg()[SQL::CREATE_GACCOUNT].asString();
		int chips = 0;
#ifdef DEBUG
		chips = 10000;
#endif
		sprintf(sql, sql_str.c_str(), roleid,account.c_str(), pwd.c_str(), "",sex,chips);

		//LOG((INFO_LOG,"=====sql:%s",sql));
		int result = state->execute(sql);
		if (result < 0)
		{
			this->destory(NULL, state);
			return ERROR_SERVER_PROBLEM;
		}
		this->destory(NULL, state);
		return 0;
	}
	catch (SQLException& e)
	{
		LOG((ERROR_LOG,"MySqlDB::create_global_role-ErrorCode:[%d],SQLState:[%s] description:[%s]",
				e.getErrorCode(),e.getSQLState().c_str(),e.what()));
	}
	return -1;
}

/*
 * if succ return role_id,else return error code
 */
int MySqlDB::check_account(DBPlayer *player)
{
	try
	{
		MyConnection conn = this->get_conn();
		if (NULL == conn.conn_)
		{
			return -1;
		}
		sql::Statement *state = conn.conn_->createStatement();
		if (NULL == state)
		{
			return -1;
		}

		std::stringstream q_stream;
		q_stream << "select * from gAccount where account='" << player->account()<< "';";

		sql::ResultSet* rs = state->executeQuery(q_stream.str());
		if (NULL == rs)
		{
			this->destory(rs, state);
			return ERROR_SERVER_PROBLEM;
		}
		if (rs->rowsCount() <= 0)
		{
			this->destory(rs, state);
			return ERROR_ACCOUNT_NOT_EXIST;
		}

		int role_id = -1;
		std::string tmp_pwd ="";
		if (rs->next())
		{
			role_id = rs->getInt(UsersRow::ROLE_ID);
			tmp_pwd =  rs->getString(UsersRow::PASSWD);
			player->role_id(role_id);
			player->sex(rs->getInt(UsersRow::SEX));
			player->chips(rs->getInt(UsersRow::CHIPS));
		}
		if(tmp_pwd!=player->pwd_)
		{
			return ERROR_PASSWORD;
		}
		this->destory(rs, state);
		return role_id;
	}
	catch (SQLException& e)
	{
		LOG((ERROR_LOG,"MySqlDB::check_account-ErrorCode:[%d],SQLState:[%s] description:[%s]",
				e.getErrorCode(),e.getSQLState().c_str(),e.what()));
	}
	return -1;
}

int MySqlDB::get_total_chips(int roleid)
{
	try
	{
		MyConnection conn = this->get_conn();
		if (NULL == conn.conn_)
		{
			return 0;
		}
		sql::Statement *state = conn.conn_->createStatement();
		if (NULL == state)
		{
			return 0;
		}

		std::stringstream q_stream;
		q_stream << "select chips from gAccount where roleid='" << roleid<< "';";

		sql::ResultSet* rs = state->executeQuery(q_stream.str());
		if (NULL == rs || rs->rowsCount() <= 0)
		{
			this->destory(rs, state);
			return 0;
		}

		int chips = 0;
		if (rs->next())
		{
			chips = rs->getInt(UsersRow::CHIPS);
		}
		this->destory(rs, state);
		return chips;
	}
	catch (SQLException& e)
	{
		LOG((ERROR_LOG,"MySqlDB::get_total_chips-ErrorCode:[%d],SQLState:[%s] description:[%s]",
				e.getErrorCode(),e.getSQLState().c_str(),e.what()));
	}
	return 0;
}

int MySqlDB::borrow_chips(const int roleid,const int &chips)
{
	try
	{
		MyConnection conn = this->get_conn();
		if (NULL == conn.conn_)
		{
			return ERROR_SERVER_PROBLEM;
		}
		sql::Statement *state = conn.conn_->createStatement();
		if (NULL == state)
		{
			return ERROR_SERVER_PROBLEM;
		}

		std::string sql_str= "update gAccount set chips=chips-%d where roleid=%d and chips>=%d limit 1;";
		char sql[256]={0};
		sprintf(sql,sql_str.c_str(),chips,roleid,chips);

		int rows = state->executeUpdate(std::string(sql));
		if(rows <= 0)
		{
			return ERROR_LACK_CHIPS;
		}
		this->destory(NULL, state);
		return 0;
	}
	catch (SQLException& e)
	{
		LOG((ERROR_LOG,"MySqlDB::borrow_chips-ErrorCode:[%d],SQLState:[%s] description:[%s]",
				e.getErrorCode(),e.getSQLState().c_str(),e.what()));
	}
	return ERROR_SERVER_PROBLEM;
}

int MySqlDB::giveback_chips(const int roleid,const int &chips)
{
	try
	{
		MyConnection conn = this->get_conn();
		if (NULL == conn.conn_)
		{
			return ERROR_SERVER_PROBLEM;
		}
		sql::Statement *state = conn.conn_->createStatement();
		if (NULL == state)
		{
			return ERROR_SERVER_PROBLEM;
		}

		std::string sql_str= "update gAccount set chips=chips+%d where roleid=%d;";
		char sql[256]={0};
		sprintf(sql,sql_str.c_str(),chips,roleid);

		int rows = state->executeUpdate(std::string(sql));
		if(rows<= 0)
		{
			return ERROR_SERVER_PROBLEM;
		}
		this->destory(NULL, state);
		return 0;
	}
	catch (SQLException& e)
	{
		LOG((ERROR_LOG,"MySqlDB::giveback_chips-ErrorCode:[%d],SQLState:[%s] description:[%s]",
				e.getErrorCode(),e.getSQLState().c_str(),e.what()));
	}
	return ERROR_SERVER_PROBLEM;
}
